package jp.sourceforge.akjrcp.textinsert;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class TextInsertInputStream extends InputStream{
private String targetText;
//private String encoding;
private String insertText;
public static final int BEFORE=0;
public static final int AFTER=1;
public static final int REPLACE=2;
private int type;
//private boolean doAll;
private boolean ignore;
private InputStream input;
private int[] buffers;
private int bufferposition;
private int[] checkbytes;
private String encode;
private Log log=LogFactory.getLog(TextInsertInputStream.class);
public TextInsertInputStream(InputStream input,String targetText,String insertText,int mode,String encode){
	this.input=input;
	this.targetText=targetText;
	this.insertText=insertText;
	type=mode;
	this.encode=encode;
	try {
		byte[] bts=targetText.getBytes(encode);
		checkbytes=new int[bts.length];
		for (int i = 0; i < bts.length; i++) {
			checkbytes[i]=bts[i]& 0xff;
		}
	} catch (UnsupportedEncodingException e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}
public int read() throws IOException {
	if(buffers!=null && bufferposition<buffers.length){
		int r=buffers[bufferposition];
		bufferposition++;
		if(bufferposition>=buffers.length){
			buffers=null;
			bufferposition=0;
		}
		return r;
	}else{
		int b=input.read();
		if(b==-1){
			return b;
		}else{
			ByteArrayOutputStream bout=new ByteArrayOutputStream();
			bout.write(b);
			for (int i = 0; i < checkbytes.length; i++) {
				if(checkbytes[i]==b || (ignore && Character.toLowerCase(b)== Character.toLowerCase(checkbytes[i]))){
					int vs[]=toInts(bout.toByteArray());
					log.debug("mutch:"+(char)b);
					//completely mutch!
					if(i==checkbytes.length-1){
						
					log.debug("last:"+(char)b);
					int[] ins=toInts(insertText.getBytes(encode));
					if(type==BEFORE){
					buffers=new int[checkbytes.length+ins.length];
					System.arraycopy(ins,0,buffers,0,ins.length);
					System.arraycopy(vs,0,buffers,ins.length,vs.length);
					
					}else if(type==AFTER){
						buffers=new int[checkbytes.length+ins.length];
						
						
						System.arraycopy(vs,0,buffers,0,vs.length);
						System.arraycopy(ins,0,buffers,vs.length,ins.length);
					}else if(type==REPLACE){
						buffers=ins;
					}
					break;
					}else{
						//
						b=input.read();
						bout.write(b);
					}
				}else{
					log.debug("fail:"+(char)b+", hope="+(char)checkbytes[i]);
					buffers=new int[i+1];
					int vs[]=toInts(bout.toByteArray());
					System.arraycopy(vs,0,buffers,0,i);
					buffers[buffers.length-1]=b;
					break;
				}
			}
			return read();
		}
	}
}
private int[] toInts(byte[] bytes){
	int[] ints=new int[bytes.length];
	for (int i = 0; i < ints.length; i++) {
		ints[i]=0xff & bytes[i];
	}
	return ints;
}
public boolean isIgnore() {
	return ignore;
}
public void setIgnore(boolean ignore) {
	this.ignore = ignore;
}

public void close() throws IOException {
	input.close();
}

}
